package com.spa.application.service.shop;

import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.http.Header;
import com.spa.application.command.Login;
import com.spa.application.dto.login.LoginDTO;
import com.spa.application.dto.login.LoginUser;
import com.spa.domain.entity.ShopUser;
import com.spa.domain.service.*;
import com.spa.infrastructure.enums.dict.base.RequestSourceEnum;
import com.spa.infrastructure.exception.SpaException;
import com.spa.infrastructure.service.sms.GenerateSmsCodeKey;
import com.spa.infrastructure.service.sms.SmsProvider;
import com.spa.infrastructure.util.*;
import eu.bitwalker.useragentutils.UserAgent;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;

@Slf4j
@Service
public class ShopLoginApplicationService {

    @Resource
    private RedisUtil redisUtil;

    @Resource
    private ShopUserService shopUserService;

    @Resource
    private GenerateSmsCodeKey smsCodeKey;

    @Resource
    private SmsProvider smsProvider;

    public void sendSms(String phone) {
        String key = smsCodeKey.generateSmsCodeKey(phone, RequestSourceEnum.Shop.getCode());
        ShopUser shopUser = shopUserService.getShopUserByPhone(phone);
        if (BeanUtil.isEmpty(shopUser)) {
            throw new SpaException("用户不存在");
        }
        if (ObjectUtil.isNotNull(shopUser)) {
            if (StringUtils.isNotEmpty(shopUser.getOwnerPhone())) {
                phone = shopUser.getOwnerPhone();
            }
        }
        smsProvider.sendVerificationCode(phone, key);
    }
    /**
     * 短信登录
     *
     * @return token
     */
    public LoginDTO smsLogin(Login login, RequestSourceEnum requestSourceEnum) {
        String token = "";
        LoginUser loginUser = new LoginUser();
        ShopUser shopUser = shopUserService.getShopUserByPhone(login.getPhone());
        if (BeanUtil.isEmpty(shopUser)) {
            throw new SpaException("用户不存在");
        }
        loginUser.setUserId(shopUser.getId());
        loginUser.setShopUser(shopUser);
        //校验短信
        validateCaptchaSms(login, requestSourceEnum);
        if (BeanUtil.isEmpty(loginUser)) {
            throw new SpaException("用户不存在");
        }
        token = getLoginToken(requestSourceEnum, loginUser);
        return new LoginDTO(token, null);
    }

    /**
     * 获取登录 生成token
     *
     * @return token
     */
    public String getLoginToken(RequestSourceEnum rs, LoginUser lu) {
        try {
            StpUtil.logout(lu.getUserId());
            UserAgent userAgent = UserAgent.parseUserAgentString(ServletUtils.getRequest().getHeader(Header.USER_AGENT.getValue()));
            //区分手机与pc 同端互斥
            StpUtil.login(lu.getUserId(), rs.getCode());
            LoginUser loginUser = new LoginUser(lu, userAgent, rs);
            if (BeanUtil.isNotEmpty(lu.getShopUser())) {
                loginUser.setShopId(lu.getShopUser().getShopId());
            } else if (BeanUtil.isNotEmpty(lu.getMassagist())) {
                loginUser.setShopId(lu.getMassagist().getShopId());
            }
            SessionUtil.setUser(loginUser);
        } catch (Exception e) {
            Assert.isTrue(false, "生成token出错，" + e.getMessage());
        }
        // 生成token
        return StpUtil.getTokenValue();
    }


    /**
     * 手机短信校验
     *
     * @param login Login
     * @return 结果
     */
    public void validateCaptchaSms(Login login, RequestSourceEnum requestSource) {
        Assert.isTrue(StringUtils.isNotEmpty(login.getPhone()), "请确认手机号是否正常输入");
        Assert.isTrue(StringUtils.isNotEmpty(login.getSmsCode()), "请确验证码是否正常输入");
        String verifyKey = smsCodeKey.generateSmsCodeKey(login.getPhone(), requestSource.getCode());
        log.info("{}", verifyKey);
        String smsCaptcha = redisUtil.get(verifyKey);
        if (smsCaptcha == null) {
            throw new SpaException("短信验证码错误");
        }
        if (!login.getSmsCode().equalsIgnoreCase(smsCaptcha)) {
            throw new SpaException("验证码错误");
        }
    }

}
